home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mint110s / asm.y next >
Text File  |  1993-08-16  |  6KB  |  278 lines

  1.  
  2. %{
  3. #define YYSTYPE char *
  4.  
  5. #include "asmtrans.h"
  6. %}
  7.  
  8. %token WORD
  9. %token WHITESP
  10. %token EOLN
  11. %token STRING
  12. %token DEFINECMD
  13. %token INCLUDECMD
  14. %token IFDEFCMD
  15. %token IFNDEFCMD
  16. %token ELSECMD
  17. %token ENDIFCMD
  18.  
  19. /* Grammar follows */
  20. %%
  21. input:
  22.         | input line
  23. ;
  24.  
  25. line:    EOLN        { emit($1); }
  26.         /* note that emit() will automatically free the memory,
  27.            and will also check the hidecnt variable */
  28.     | label EOLN    { emit($1); emit($2); }
  29.     | opline EOLN    { emit($1); emit($2); }
  30.     | label opline EOLN    { emit($1); emit($2);
  31.             emit($3); }
  32.     | INCLUDECMD WHITESP STRING EOLN { if (!hidecnt) do_include($3); free($3); }
  33.     | INCLUDECMD WHITESP WORD EOLN { if (!hidecnt) do_include($3); free($3); }
  34.     | DEFINECMD WHITESP WORD WHITESP STRING EOLN {
  35.         if (!hidecnt) do_define($3, $5); free($3); free($5); }
  36.     | DEFINECMD WHITESP WORD WHITESP operand EOLN {
  37.         if (!hidecnt) do_define($3, $5); free($3); free($5); }
  38.     | IFDEFCMD WHITESP WORD EOLN { do_ifdef($3); free($3); }
  39.     | IFNDEFCMD WHITESP WORD EOLN { do_ifndef($3); free($3); }
  40.     | ELSECMD EOLN { do_else(); }
  41.     | ENDIFCMD EOLN { do_endif(); } 
  42. ;
  43.  
  44. opline:    WHITESP opcode        { $$ = do_ops("", $2, "", ""); free($2); }
  45.     | WHITESP opcode WHITESP ops
  46.             { $$ = do_ops("", $2, $3, $4);
  47.              free($2); free($3); free($4); }
  48.     | WORD WHITESP opcode    { $$ = do_ops($1, $3, "", ""); free($1); free($3); }
  49.     | WORD WHITESP opcode WHITESP ops
  50.             { $$ = do_ops($1, $3, $4, $5);
  51.              free($1); free($3); free($4); free($5);}
  52. ;
  53.  
  54. ops: operand { $$ = $1; }
  55.     | operand ',' ops { $$ = concat3($1, ",", $3);
  56.                 free($1); free($3); }
  57. ;
  58.  
  59. opcode: WORD    { $$ = wordlookup($1); free($1); }
  60. ;
  61.  
  62. label: WORD ':' { $$ = concat($1, ":"); free($1); }
  63.  
  64. operand: basic    {$$ = $1; }
  65.     | '#' basic {$$ = immediate($2); free($2); }
  66.     | '(' basic ')' {$$ = indirect($2); free($2); }
  67.     | '(' basic ')' '+' {$$ = postinc($2); free($2); }
  68.     | '-' '(' basic ')' {$$ = predec($3); free($3); }
  69.     | basic '(' basic ')' {$$ = indexed($1, $3); free($1); free($3); }
  70.     | '(' basic ')' WORD {$$ = sizedop($2, $4); free($2); free($4); }
  71.     | basic '(' basic ',' basic ')' {$$ = twoindex($1, $3, $5);
  72.                 free($1); free($3); free($5); }
  73.     | basic '{' basic ':' basic '}' {$$ = bitfield($1, $3, $5);
  74.             free($1); free($3); free($5); }
  75.     | '(' '[' basic ',' basic ']' ',' basic ',' basic ')'
  76.        { $$=postindex($3,$5,$8,$10); 
  77.          free($3); free($5); free($8); free($10); }        
  78.     | '(' '[' basic ',' basic ',' basic ']' ',' basic ')'
  79.        { $$=preindex($3,$5,$7,$10); 
  80.          free($3); free($5); free($7); free($10); }        
  81.     | '(' '[' basic ']' ')'
  82.        { $$=postindex0($3); 
  83.          free($3); }
  84.     | '(' '[' basic ']' ','  basic ')'
  85.        { $$=postindex1($3,$6); 
  86.          free($3); free($6); }                          
  87. ;
  88.  
  89. basic: basexpr { $$ = $1; }
  90.     | basexpr op basic { $$ = concat3($1, $2, $3); free($1); free($2); free($3); }
  91.     | '-' basic { $$ = concat("-", $2); free($2); }
  92.  
  93. basexpr: WORD {$$ = wordlookup($1); free($1); }
  94.     | '$' WORD {$$ = hexop($2); free($2);}
  95. ;
  96.  
  97. op:     '+' { $$ = strdup("+"); }
  98.     | '-' { $$ = strdup("-"); }
  99.     | '*' { $$ = strdup("*"); }
  100.     | '/' { $$ = strdup("/"); }
  101. ;
  102. %%
  103. #include <setjmp.h>
  104.  
  105. jmp_buf start;
  106.  
  107. #ifdef NATIVEATARI
  108. #define STACK 32*1024L
  109. #ifdef LATTICE
  110. long _STACK = STACK;
  111. #endif
  112. #ifdef __GNUC__
  113. long _stksize = STACK;
  114. #endif
  115.  
  116. static void
  117. hit_return()
  118. {
  119.     printf("Hit return to continue\n");
  120.     fflush(stdout);
  121.     getchar();
  122. }
  123. #endif
  124.  
  125. void usage()
  126. {
  127.     fprintf(stderr, "Usage: asmtrans [-gas][-asm][-o outfile] infile\n");
  128.     exit(2);
  129. }
  130.  
  131. int errors = 0;
  132.  
  133. void
  134. do_include(file)
  135.     char *file;
  136. {
  137.     jmp_buf save;
  138.     FILE *oldin, *f;
  139.  
  140.     f = fopen(file, "rt");
  141.     if (!f) {
  142.         perror(file);
  143.         return;
  144.     }
  145.     bcopy(start, save, sizeof(jmp_buf));
  146.     oldin = infile;
  147.     infile = f;
  148.     setjmp(start);
  149.     yyparse();
  150.     fclose(f);
  151.     infile = oldin;
  152.     bcopy(save, start, sizeof(jmp_buf));
  153.     longjmp(start,1);
  154. }
  155.  
  156. /* set up initial definitions based on syntax type */
  157.  
  158. void
  159. do_initial_defs()
  160. {
  161.     if (syntax == GAS) {
  162.         do_define("mmusr", "psr");
  163.         do_define("fpiar", "fpi");
  164.         do_define("XREF", ".globl");
  165.         do_define("XDEF", ".globl");
  166.         do_define("TEXT", ".text");
  167.         do_define("DATA", ".data");
  168.     /* gas doesn't have a .bss directive */
  169.         do_define("BSS", ".data");
  170.         do_define("END", "| END");
  171.         do_define("dc.l", ".long");
  172.         do_define("dc.w", ".word");
  173.         do_define("dc.b", ".byte");
  174.     } else if (syntax == ASM) {
  175.         do_define("TEXT", "SECTION TEXT,CODE");
  176.         do_define("DATA", "SECTION DATA,DATA");
  177.         do_define("BSS", "SECTION BSS,BSS");
  178.     }
  179. }
  180.  
  181. int
  182. main (argc, argv)
  183.     int argc; char **argv;
  184. {
  185.     FILE *f;
  186. #ifdef NATIVEATARI
  187.     if (!argv[0] || !argv[0][0])    /* run from desktop? */
  188.         atexit(hit_return);
  189. #endif
  190.     argv++;
  191.     outfile = stdout;
  192.  
  193.     while (*argv) {
  194.         if (!strcmp(*argv, "-o")) {
  195.             argv++;
  196.             if (*argv == 0) {
  197.                 fprintf(stderr, "missing argument to -o\n");
  198.                 usage();
  199.             }
  200.             f = fopen(*argv, "wt");
  201.             if (!f)
  202.                 perror(*argv);
  203.             else
  204.                 outfile = f;
  205.             argv++;
  206.         } else if (!strcmp(*argv, "-gas")) {
  207.             argv++;
  208.             syntax = GAS;
  209.         } else if (!strcmp(*argv, "-asm")) {
  210.             argv++;
  211.             syntax = ASM;
  212.         } else if (!strcmp(*argv, "-purec")) {
  213.             argv++;
  214.             syntax = PUREC;
  215.         } else if (!strncmp(*argv, "-D", 2)) {
  216.             char *word, *defn;
  217.             word = *argv+2;
  218.             defn = index(word,'=');
  219.             if (defn)
  220.                 *defn++ = '\0';
  221.             else
  222.                 defn = "1";
  223.             if (*word) do_define(word,defn);
  224.             argv++;
  225.         } else if (!strcmp(*argv, "--")) {
  226.             argv++;
  227.             break;
  228.         } else {
  229.             if (**argv == '-') {
  230.                 fprintf(stderr, "unknown option: %s\n",
  231.                     *argv);
  232.                 usage();
  233.             }
  234.             break;
  235.         }
  236.     }
  237.  
  238.     do_initial_defs();
  239.  
  240.     if (*argv == 0) {
  241.         setjmp(start);
  242.         infile = stdin;
  243.         yyparse();
  244.     } else {
  245.         while(*argv) {
  246.         if (!(f = fopen(*argv, "rt")))
  247.             perror(*argv);
  248.         else {
  249.             infile = f;
  250.             setjmp(start);
  251.             yyparse();
  252.             fclose(f);
  253.         }
  254.         argv++;
  255.         }
  256.     }
  257.  
  258.     if (ifstkptr != 0) {
  259.         fputs("%ifdef without matching %endif\n", stderr);
  260.         errors++;
  261.     }
  262.     return errors;
  263. }
  264.  
  265. void
  266. yyerror (s)  /* Called by yyparse on error */
  267.      char *s;
  268. {
  269.     errors++;
  270.     printf("%s\n", s);
  271.     longjmp(start, 1);
  272. }
  273.  
  274. void dbgmsg(s) char *s;
  275. {
  276.     fprintf(stderr, "%s\n", s);
  277. }
  278.